'use client';

import { useSearchParams } from 'next/navigation';
import React, { useState, useEffect, Suspense } from 'react';
import { Card, Row, Col, Typography, Form, Select, Input, InputNumber, Button, Slider, Space, Divider, Tooltip, message } from 'antd';
import { RedoOutlined, DownloadOutlined, CopyOutlined, SettingOutlined } from '@ant-design/icons';
import Image from 'next/image';
import AdminLayout from '../AdminLayout';
import styles from './TextToImage.module.scss';
import { safeDownloadImage } from '../../../utils/domUtils';
import { PromptGenerator, TagsToggle } from '../../../components';
import { useRouter } from 'next/navigation';

// 扩展Window接口以支持ClipboardItem
declare global {
  interface Window {
    ClipboardItem: typeof ClipboardItem;
  }
}

const { Title, Paragraph } = Typography;
const { Option } = Select;
const { TextArea } = Input;

// 从template.json转换后的风格配置类型
interface StyleConfig {
  id: string;
  name: string;
  description: string;
  image: string;
  base_model: string;
  lora_model: string;
  lora_output_name: string;
  lora_weight: number;
  vae: string;
  prompt: string;
  negative_prompt: string;
  width: number;
  height: number;
  batch_size: number;
  n_iter: number;
  steps: number;
  cfg_scale: number;
  sampler_name: string;
  scheduler: string;
  seed: number;
  clip_skip: number;
}

// 采样器类型
interface Sampler {
  name: string;
  aliases: string[];
  options: Record<string, string>;
}

const resolutionPresets = [
  { label: '1:1 (512×512)', width: 512, height: 512 },
  { label: '3:4 (384×512)', width: 384, height: 512 },
  { label: '4:3 (512×384)', width: 512, height: 384 },
  { label: '16:9 (768×432)', width: 768, height: 432 },
  { label: '9:16 (432×768)', width: 432, height: 768 },
];

const TextToImageContent: React.FC = () => {
  const [form] = Form.useForm<StyleConfig>();
  const [imageUrl, setImageUrl] = useState<string | null>(null);
  const [isGenerating, setIsGenerating] = useState<boolean>(false);
  const [steps, setSteps] = useState<number>(30);
  const [cfgScale, setCfgScale] = useState<number>(7);
  const [generationParams, setGenerationParams] = useState<StyleConfig | null>(null);
  const [selectedStyle, setSelectedStyle] = useState<string>('realistic_portrait');
  const [currentStyle, setCurrentStyle] = useState<StyleConfig | null>(null);
  const [styleCards, setStyleCards] = useState<StyleConfig[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [samplers, setSamplers] = useState<Sampler[]>([]);
  const router = useRouter();

  const searchParams = useSearchParams();

  // 获取采样器数据
  useEffect(() => {
    const fetchSamplers = async () => {
      try {
        const response = await fetch('/api/sd/samplers');
        if (!response.ok) {
          throw new Error('Failed to fetch samplers');
        }
        const samplersData: Sampler[] = await response.json();
        setSamplers(samplersData);
      } catch (error) {
        console.error('获取采样器数据失败:', error);
        message.error('获取采样器数据失败');
      }
    };

    fetchSamplers();
  }, []);

  useEffect(() => {
    fetch('/api/license/status').then(async (res) => {
      const result = await res.json();
      if (result.status !== 200) {
        router.push('/');
      }
    }).catch(() => {
      router.push('/');
    });
  }, []);

  // 转换template.json数据为Txt2ImgRequest格式
  const convertTemplateToRequest = (templateData: any): StyleConfig => {
    return {
      id: templateData.id,
      name: templateData.name,
      description: templateData.description,
      image: templateData.image,
      base_model: templateData.base_model,
      lora_model: templateData.lora_model,
      lora_output_name: templateData.lora_output_name,
      lora_weight: templateData.lora_weight,
      vae: templateData.vae,
      prompt: templateData.prompt || '',
      negative_prompt: templateData.negative_prompt || '',
      width: templateData.width || 512,
      height: templateData.height || 512,
      batch_size: 1,
      n_iter: 1,
      steps: templateData.steps || 30,
      cfg_scale: templateData.cfg_scale || 7,
      sampler_name: templateData.sampler_name || 'Euler a',
      scheduler: templateData.scheduler,
      seed: templateData.seed || -1,
      clip_skip: templateData.clip_skip,
    };
  };

  // 在页面加载时读取template.json
  useEffect(() => {
    const loadTemplateData = async () => {
      try {
        const response = await fetch('/api/templates-db');
        if (!response.ok) {
          throw new Error('Failed to load template data from API');
        }
        
        const result = await response.json();
        if (!result.success) {
          throw new Error(result.error || 'Failed to load template data from API');
        }
        const data = result.data;
        // 从API获取的数据中筛选出txt2img类型的模板
        const txt2imgData = data.filter((item: any) => item.type === 'txt2img');
        
        // 转换数据并创建styleCards
        const convertedStyleCards: StyleConfig[] = txt2imgData.map((item: any) => convertTemplateToRequest(item));
        
        setStyleCards(convertedStyleCards);

        const dataParam = searchParams.get('data');
        if (dataParam) {
          try {
            const decodedData = JSON.parse(decodeURIComponent(dataParam));
            // 假设 decodedData 是 StyleConfig 类型
            setSelectedStyle(decodedData.id);
            setCurrentStyle(decodedData);
            form.setFieldsValue(decodedData);
            setSteps(decodedData.steps);
            setCfgScale(decodedData.cfg_scale);
          } catch (error) {
            console.error('解析 data 参数失败:', error);
            loadDefaultStyle(convertedStyleCards);
          }
        } else {
          loadDefaultStyle(convertedStyleCards);
        }
      } catch (error) {
        console.error('加载模板数据失败:', error);
        message.error('加载模板数据失败，使用默认配置');
        
        // 使用默认的styleCards作为后备
        const defaultStyleCards: StyleConfig[] = [
          {
            id: 'realistic_portrait',
            name: '写实人物肖像',
            description: '真实照片效果',
            image: '/text-img/xs.png',
            base_model: 'majicMIX realistic_v7.safetensors',
            lora_model: '写实摄影平面模特气质美女v1.safetensors',
            lora_output_name: '写实摄影平面模特气质美女v1.safetensors',
            lora_weight: 0.8,
            vae: 'vae-ft-mse-840000-ema-pruned.safetensors',
            prompt: 'a beautiful landscape, high quality',
            negative_prompt: 'blurry, low quality',
            width: 512,
            height: 512,
            batch_size: 1,
            n_iter: 1,
            steps: 30,
            cfg_scale: 7,
            sampler_name: 'Euler a',
            scheduler: 'Karras',
            seed: -1,
            clip_skip: 2,
          }
        ];
        setStyleCards(defaultStyleCards);
      } finally {
        setIsLoading(false);
      }
    };

    loadTemplateData();
  }, []);

  const loadDefaultStyle = (convertedStyleCards: StyleConfig[]) => {
    if (convertedStyleCards.length > 0) {
      const defaultStyle = convertedStyleCards[0];
      setSelectedStyle(defaultStyle.id);

      // 更新表单的默认值
      form.setFieldsValue({
        id: defaultStyle.id,
        prompt: defaultStyle.prompt,
        negative_prompt: defaultStyle.negative_prompt,
        sampler_name: defaultStyle.sampler_name,
        steps: defaultStyle.steps,
        cfg_scale: defaultStyle.cfg_scale,
        width: defaultStyle.width,
        height: defaultStyle.height,
        seed: defaultStyle.seed,
      });
      
      // 更新本地状态
      setCurrentStyle(defaultStyle);
      setSteps(defaultStyle.steps);
      setCfgScale(defaultStyle.cfg_scale);
    }
  }

  const handleGenerate = async (values: StyleConfig) => {
    setIsGenerating(true);
    setGenerationParams(values);
    
    try {
      // 构造发送到API的数据
      const requestData = {
        prompt: values.prompt + `<lora:${currentStyle?.lora_output_name}:${currentStyle?.lora_weight}>,`,
        negative_prompt: values.negative_prompt || "blurry, low quality",
        override_settings: {
          "sd_model_checkpoint": currentStyle?.base_model,
          "sd_vae": currentStyle?.vae,
          "CLIP_stop_at_last_layers": currentStyle?.clip_skip,
        },
        override_settings_restore_afterwards: false,
        width: values.width || 512,
        height: values.height || 512,
        steps: steps || 30,
        cfg_scale: cfgScale || 7,
        sampler_name: values.sampler_name || "Euler a",
        batch_size: 1,
        n_iter: 1,
        seed: values.seed || -1,
        scheduler: currentStyle?.scheduler || "karras",
      };

      // 调用API
      const response = await fetch('/api/sd/txt2img', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(requestData)
      });

      if (!response.ok) {
        const errorData = await response.json();
        
        // 检查是否是敏感词错误
        if (response.status === 400 && errorData.error && errorData.error.includes('敏感词汇')) {
          // 显示敏感词检测的详细错误信息
          message.error({
            content: (
              <div>
                <div style={{ fontWeight: 'bold', marginBottom: '8px' }}>内容检测失败</div>
                <div style={{ marginBottom: '4px' }}>{errorData.error}</div>
                {errorData.detail && (
                  <div style={{ fontSize: '12px', color: '#666' }}>{errorData.detail}</div>
                )}
              </div>
            ),
            duration: 8, // 显示8秒，给用户足够时间阅读
          });
        } else {
          // 其他类型的错误
          const errorMessage = errorData.detail || errorData.error || `HTTP error! status: ${response.status}`;
          message.error(`生成失败: ${errorMessage}`);
        }
        
        setImageUrl(null);
        return;
      }

      const data = await response.json();
      
      // 检查返回的数据是否有图像
      if (data.images && data.images.length > 0) {
        // 将Base64图像数据转换为URL
        const base64Image = data.images[0];
        setImageUrl(`data:image/png;base64,${base64Image}`);
      } else {
        message.error('未收到有效的图像数据');
        setImageUrl(null);
      }
    } catch (error) {
      console.error('生成图像时出错:', error);
      
      // 检查是否是网络错误或其他类型错误
      if (error instanceof Error) {
        if (error.message.includes('敏感词汇')) {
          message.error({
            content: '检测到敏感内容，请修改提示词后重试',
            duration: 6,
          });
        } else {
          message.error(`生成图像失败: ${error.message}`);
        }
      } else {
        message.error('生成图像失败，请稍后重试');
      }
      
      setImageUrl(null);
    } finally {
      setIsGenerating(false);
    }
  };

  const handleRegenerate = () => {
    if (generationParams) {
      handleGenerate(generationParams);
    }
  };

  const handleApplyResolutionPreset = (width: number, height: number) => {
    form.setFieldsValue({ width, height });
  };

  const handleRandomSeed = () => {
    const randomSeed = Math.floor(Math.random() * 1000000);
    form.setFieldsValue({ seed: randomSeed });
  };

  const handleDownloadImage = () => {
    if (!imageUrl) {
      message.error('没有可下载的图片');
      return;
    }

    try {
      // 生成文件名：使用当前时间戳和随机数
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
      const randomNum = Math.floor(Math.random() * 1000);
      const fileName = `generated-image-${timestamp}-${randomNum}.png`;
      
      // 使用安全的下载函数
      safeDownloadImage(imageUrl, fileName);
      message.success('图片下载成功');
    } catch (error) {
      console.error('下载图片时出错:', error);
      message.error('下载图片失败，请稍后重试');
    }
  };

  const handleCopyImage = async () => {
    if (!imageUrl) {
      message.error('没有可复制的图片');
      return;
    }

    try {
      // 将base64图片转换为Blob
      const response = await fetch(imageUrl);
      const blob = await response.blob();
      
      // 检查是否支持Clipboard API
      if (navigator.clipboard && window.ClipboardItem) {
        // 使用现代Clipboard API
        const clipboardItem = new ClipboardItem({
          [blob.type]: blob
        });
        await navigator.clipboard.write([clipboardItem]);
        message.success('图片已复制到剪贴板');
      } else {
        // 降级方案：复制图片URL
        await navigator.clipboard.writeText(imageUrl);
        message.success('图片URL已复制到剪贴板');
      }
    } catch (error) {
      console.error('复制图片时出错:', error);
      
      // 如果Clipboard API失败，尝试复制URL
      try {
        await navigator.clipboard.writeText(imageUrl);
        message.success('图片URL已复制到剪贴板');
      } catch (fallbackError) {
        console.error('复制URL也失败:', fallbackError);
        message.error('复制失败，请手动保存图片');
      }
    }
  };

  const handleStyleSelect = (styleValue: string) => {
    setSelectedStyle(styleValue);
    
    // 找到选中的风格配置
    const selectedStyleConfig = styleCards.find(style => style.id === styleValue);
    if (selectedStyleConfig) {
      // 自动填充表单字段
      form.setFieldsValue({
        id: styleValue,
        prompt: selectedStyleConfig.prompt,
        negative_prompt: selectedStyleConfig.negative_prompt,
        sampler_name: selectedStyleConfig.sampler_name,
        steps: selectedStyleConfig.steps,
        cfg_scale: selectedStyleConfig.cfg_scale,
        width: selectedStyleConfig.width,
        height: selectedStyleConfig.height,
        seed: selectedStyleConfig.seed,
      });
      
      // 更新本地状态
      setCurrentStyle(selectedStyleConfig);
      setSteps(selectedStyleConfig.steps);
      setCfgScale(selectedStyleConfig.cfg_scale);
    }
  };

  return (
    <AdminLayout pageTitle="文生图">
      <div className={styles.container}>
        <Row gutter={24}>
          {/* 左侧配置表单 */}
          <Col xs={24} lg={12}>
            <Card title="生成配置" variant="borderless" className={styles.configCard}>
              {/* 风格选择卡片 */}
              <div className={styles.styleSection}>
                <div className={styles.styleTitle}>风格选择</div>
                {isLoading ? (
                  <div className={styles.loadingContainer}>
                    <div className={styles.loadingText}>正在加载风格配置...</div>
                  </div>
                ) : (
                  <div className={styles.styleCards}>
                    {styleCards.map((style) => (
                      <div
                        key={style.id}
                        className={`${styles.styleCard} ${selectedStyle === style.id ? styles.selected : ''}`}
                        onClick={() => handleStyleSelect(style.id)}
                      >
                        <div className={styles.styleImage}>
                          <Image
                            src={style.image}
                            alt={style.name}
                            width={200}
                            height={150}
                            className={styles.image}
                            priority
                          />
                          {selectedStyle === style.id && (
                            <div className={styles.selectedOverlay}>
                              <div className={styles.checkmark}>✓</div>
                            </div>
                          )}
                        </div>
                        <div className={styles.styleInfo}>
                          <div className={styles.styleName}>{style.name}</div>
                          <div className={styles.styleDescription}>{style.description}</div>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>

              <Form
                form={form}
                layout="vertical"
                onFinish={handleGenerate}
                initialValues={{
                  base_model: 'stable-diffusion-xl',
                  style: selectedStyle,
                  steps: steps,
                  cfg_scale: cfgScale,
                  width: 512,
                  height: 512,
                  sampler: 'Euler a',
                  seed: -1,
                }}
              >

                <Form.Item name="style" label="风格选择" rules={[{ required: true }]} style={{ display: 'none' }}>
                  <Select>
                    {styleCards.map((style) => (
                      <Option key={style.id} value={style.id}>
                        {style.name}
                      </Option>
                    ))}
                  </Select>
                </Form.Item>

                {/* PromptGenerator组件 - 位于正向提示词输入框外部上方右对齐 */}
                <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '8px' }}>
                  <PromptGenerator
                    onInsert={(prompt, negativePrompt) => {
                      console.log('PromptGenerator onInsert called:', { prompt, negativePrompt });
                      
                      // 直接替换正向提示词输入框内容
                      console.log('Setting prompt:', prompt);
                      form.setFieldsValue({ prompt: prompt });
                      
                      // 如果有反向提示词，直接替换反向提示词输入框内容
                      if (negativePrompt) {
                        console.log('Setting negative prompt:', negativePrompt);
                        form.setFieldsValue({ negative_prompt: negativePrompt });
                      }
                      
                      // 显示成功消息
                      message.success('提示词已插入');
                    }}
                  />
                </div>

                <Form.Item name="prompt" label="正向提示词" rules={[{ required: true }]}>
                  <TextArea rows={4} placeholder="输入详细的图像描述..." />
                </Form.Item>

                {/* 标签选择器：选择后将英文标签追加到正向提示词，以英文逗号分隔 */}
                <div style={{ marginBottom: 16 }}>
                  <TagsToggle
                    buttonText="标签"
                    onSelect={(en) => {
                      const current: string = (form.getFieldValue('prompt') || '').toString();
                      const trimmed = current.trim();
                      let next = '';
                      if (!trimmed) {
                        next = en;
                      } else {
                        // 去掉可能存在的末尾逗号，统一用“, ”间隔
                        const base = trimmed.replace(/,\s*$/, '');
                        next = `${base}, ${en}`;
                      }
                      form.setFieldsValue({ prompt: next });
                    }}
                  />
                </div>

                <Form.Item name="negative_prompt" label="反向提示词">
                  <TextArea rows={3} placeholder="输入不希望在图像中出现的元素..." />
                </Form.Item>

                {/* 标签选择器（负向）：选择后将英文标签追加到反向提示词，以英文逗号分隔 */}
                <div style={{ marginBottom: 16 }}>
                  <TagsToggle
                    buttonText="标签"
                    onSelect={(en) => {
                      const current: string = (form.getFieldValue('negative_prompt') || '').toString();
                      const trimmed = current.trim();
                      let next = '';
                      if (!trimmed) {
                        next = en;
                      } else {
                        // 去掉可能存在的末尾逗号，统一用“, ”间隔
                        const base = trimmed.replace(/,\s*$/, '');
                        next = `${base}, ${en}`;
                      }
                      form.setFieldsValue({ negative_prompt: next });
                    }}
                  />
                </div>

                <Divider orientation="left">高级选项</Divider>

                <Form.Item name="sampler_name" label="采样器">
                  <Select loading={samplers.length === 0}>
                    {samplers.map((sampler) => (
                      <Option key={sampler.name} value={sampler.name}>
                        {sampler.name}
                      </Option>
                    ))}
                  </Select>
                </Form.Item>

                <Form.Item name="steps" label={`采样步数: ${steps}`}>
                  <Slider min={10} max={150} onChange={(value) => setSteps(value)} />
                </Form.Item>

                <Form.Item name="cfg_scale" label={`CFG Scale: ${cfgScale}`}>
                  <Slider min={1} max={30} step={0.5} onChange={(value) => setCfgScale(value)} />
                </Form.Item>

                <Form.Item label="分辨率">
                  <Space direction="vertical" style={{ width: '100%' }}>
                    <Space>
                      <Form.Item name="width" noStyle>
                        <InputNumber min={256} max={1024} step={64} addonBefore="宽" />
                      </Form.Item>
                      <span>x</span>
                      <Form.Item name="height" noStyle>
                        <InputNumber min={256} max={1024} step={64} addonBefore="高" />
                      </Form.Item>
                    </Space>
                    
                    <div className={styles.presetButtons}>
                      {resolutionPresets.map((preset, index) => (
                        <Button
                          key={index}
                          size="small"
                          onClick={() => handleApplyResolutionPreset(preset.width, preset.height)}
                        >
                          {preset.label}
                        </Button>
                      ))}
                    </div>
                  </Space>
                </Form.Item>

                <Form.Item name="seed" label="种子">
                  <Space>
                    <InputNumber style={{ width: '100%' }} placeholder="-1 表示随机" />
                    <Button onClick={handleRandomSeed}>随机</Button>
                  </Space>
                </Form.Item>

                <Form.Item>
                  <Button 
                    type="primary" 
                    htmlType="submit" 
                    loading={isGenerating} 
                    block
                    className={styles.generateButton}
                  >
                    生成图像
                  </Button>
                </Form.Item>
              </Form>
            </Card>
          </Col>
          
          {/* 右侧图片预览 */}
          <Col xs={24} lg={12}>
            <Card 
              title="图片预览" 
              variant="borderless" 
              className={styles.previewCard}
              extra={
                <Space>
                  <Tooltip title="重新生成">
                    <Button 
                      icon={<RedoOutlined />} 
                      disabled={!imageUrl || isGenerating} 
                      onClick={handleRegenerate}
                      loading={isGenerating}
                    />
                  </Tooltip>
                  <Tooltip title="下载图片">
                    <Button 
                      icon={<DownloadOutlined />} 
                      disabled={!imageUrl} 
                      onClick={handleDownloadImage}
                    />
                  </Tooltip>
                  <Tooltip title="复制图片">
                    <Button 
                      icon={<CopyOutlined />} 
                      disabled={!imageUrl} 
                      onClick={handleCopyImage}
                    />
                  </Tooltip>
                </Space>
              }
            >
              <div className={styles.imagePreview}>
                {isGenerating ? (
                  <div className={styles.loadingContainer}>
                    <div className={styles.loadingSpinner}></div>
                    <p>正在生成图像，请稍候...</p>
                  </div>
                ) : imageUrl ? (
                  <img src={imageUrl} alt="生成的图像" className={styles.generatedImage} />
                ) : (
                  <div className={styles.placeholderImage}>
                    <img 
                      src="/see.png" 
                      alt="预览图标" 
                      style={{ 
                        width: '80px', 
                        height: '80px', 
                        opacity: 0.6,
                        filter: 'brightness(0.8)'
                      }} 
                    />
                    <p>点击"生成图像"按钮开始创建</p>
                  </div>
                )}
              </div>

              {imageUrl && generationParams && (
                <div className={styles.imageInfo}>
                  <Divider>生成参数</Divider>
                  <Row gutter={[16, 8]}>
                    <Col span={8}><strong>模型:</strong> {currentStyle?.base_model}</Col>
                    <Col span={8}><strong>风格:</strong> {currentStyle?.name}</Col>
                    <Col span={8}><strong>采样器:</strong> {generationParams.sampler_name}</Col>
                    <Col span={8}><strong>步数:</strong> {generationParams.steps}</Col>
                    <Col span={8}><strong>CFG:</strong> {generationParams.cfg_scale}</Col>
                    <Col span={8}><strong>分辨率:</strong> {generationParams.width}x{generationParams.height}</Col>
                  </Row>
                </div>
              )}
            </Card>
          </Col>
        </Row>
      </div>
    </AdminLayout>
  );
};

const TextToImage: React.FC = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <TextToImageContent />
    </Suspense>
  );
};

export default TextToImage;